package org.datavec.linan;

import com.google.common.collect.Maps;
import org.apache.commons.collections.map.HashedMap;
import sun.misc.IOUtils;

import java.io.*;
import java.util.*;
import java.util.stream.Collectors;

public class infoTreeNode {
    //第一步获取是否购物的信息熵
    public static void main(String[] args) {
        List<Map<String,String>> initData = initData();
        String classLable = "是否购物";
        String classValue = "是";
        double zEntropy=classEntropy(initData,classLable);
        Map<String,Double> nodeEntropyMap = Maps.newHashMap();
        nodeEntropyMap.put("是否上班",0.0);
        nodeEntropyMap.put("性别",0.0);
        nodeEntropyMap.put("是否结婚",0.0);
        for(String nodeName : nodeEntropyMap.keySet()){
            double entropy =  checkEntropy(initData,nodeName,classLable,classValue);
            nodeEntropyMap.put(nodeName, (zEntropy-entropy));
            System.out.println(nodeName +" :" + (zEntropy-entropy));
        }
        Map<String,Double>  temp=nodeEntropyMap.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,(oldValue, newValue) -> oldValue, LinkedHashMap::new));
        System.out.println(zEntropy);

    }

    public static double checkEntropy(List<Map<String,String>> initData,String nodeName,String classLable,String classValue ){
        Map<String,Double> nodeEntropy=nodeEntropy(initData,nodeName);
        Map<String,Double> nodeMbEntropy=nodeMbEntropy(initData,nodeEntropy,nodeName,classLable,classValue);
        double entropy = 0.0;
        for(String type : nodeEntropy.keySet()){
            double nodeSize = nodeEntropy.get(type);
            double nodeMbSize = nodeMbEntropy.get(type);//数据集中和目标相等的数
            entropy+= nodeSize/initData.size() * (log.log2(nodeMbSize/nodeSize) + log.log2((nodeSize-nodeMbSize)/nodeSize));

        }
       return  entropy;

    }
    /**
     * 算出节点占比
     * @param initData
     * @return
     */
    public static Map<String,Double> nodeEntropy(List<Map<String,String>> initData,String nodeName){
        Map<String,Double> types= new HashMap<>();
        for (Map<String,String > data : initData()) {
            String type=data.get(nodeName);
            if(types.get(type) == null){
                types.put(type,0.0);

            }
            types.put(type,types.get(type)+1);

        }
        return types;
    }
    /**
     * 算出节点占比 与墓目标相等比例
     * @param initData
     * @return
     */
    public static Map<String,Double> nodeMbEntropy(List<Map<String,String>> initData,Map<String,Double> nodeEntropy,String nodeName,String classLable,String classValue){
        Map<String,Double> types= new HashMap<>();
        for(String type : nodeEntropy.keySet()){
            if(types.get(type) == null){
                types.put(type,0.0);
            }

            for (Map<String,String > data : initData) {
                if(data.get(classLable).equals(classValue) && data.get(nodeName).equals(type)){
                    if(types.get(type) == null){
                        types.put(type,0.0);
                    }
                    types.put(type,types.get(type)+1);
                }
            }
        }

        return types;
    }
    /**
     * 信心获取量 看看这个目标的信息熵
     * @return
     */

    public static double classEntropy(List<Map<String,String>> initData,String classLable){
        double entropy= 0.0;
        Map<String,Double> labels=new HashMap<>();
        for (Map<String, String> initDatum : initData) {
            String label=initDatum.get(classLable);
            if(labels.get(label) == null){
                labels.put( label,0.0);
            }
            labels.put( label,labels.get(label)+1);
        }
        for(String lable:labels.keySet()){
            double value=labels.get(lable);
            entropy+=log.log2(value/initData.size());
        }
        return  entropy;
    }

    public static List<Map<String,String>> initData(){
        List<Map<String,String>> datas = new ArrayList<Map<String,String>>();
        Map map = new HashMap();
        map.put("姓名","李楠");
        map.put("是否上班","上班");
        map.put("性别","男");
        map.put("是否结婚","是");
        map.put("是否购物","否");
        datas.add(map);
        map = new HashMap();
        map.put("姓名","李伟");
        map.put("是否上班","上班");
        map.put("性别","男");
        map.put("是否结婚","否");
        map.put("是否购物","是");
        datas.add(map);
        map = new HashMap();
        map.put("姓名","周俊玲");
        map.put("是否上班","上班");
        map.put("性别","女");
        map.put("是否结婚","是");
        map.put("是否购物","是");
        datas.add(map);
        map = new HashMap();
        map.put("姓名","周美");
        map.put("是否上班","上班");
        map.put("性别","男");
        map.put("是否结婚","否");
        map.put("是否购物","否");
        datas.add(map);
        map = new HashMap();
        map.put("姓名","晓光");
        map.put("是否上班","上班");
        map.put("性别","男");
        map.put("是否结婚","是");
        map.put("是否购物","是");
        datas.add(map);
        map = new HashMap();
        map.put("姓名","姜师涛");
        map.put("是否上班","休假");
        map.put("性别","男");
        map.put("是否结婚","否");
        map.put("是否购物","是");
        datas.add(map);
        map = new HashMap();
        map.put("姓名","某女");
        map.put("是否上班","休假");
        map.put("性别","女");
        map.put("是否结婚","是");
        map.put("是否购物","否");
        datas.add(map);
        map = new HashMap();
        map.put("姓名","某女1");
        map.put("是否上班","休假");
        map.put("性别","男");
        map.put("是否结婚","是");
        map.put("是否购物","是");
        datas.add(map);
        map = new HashMap();
        map.put("姓名","某男");
        map.put("是否上班","不上班");
        map.put("性别","男");
        map.put("是否结婚","是");
        map.put("是否购物","否");
        datas.add(map);
        map = new HashMap();
        map.put("姓名","牛方捷");
        map.put("是否上班","不上班");
        map.put("性别","女");
        map.put("是否结婚","是");
        map.put("是否购物","是");
        datas.add(map);
        return datas;
    }

}
